/********************************************************************************
 *      Copyright:  (C) 2023 Yangpeng
 *                  All rights reserved.
 *
 *       Filename:  get_temperature.h
 *    Description:  This file 
 *
 *        Version:  1.0.0(2023年01月05日)
 *         Author:  Yangpeng <1023769078@qq.com>
 *      ChangeLog:  1, Release initial version on "2023年01月05日 17时02分31秒"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <libgen.h>
#include <getopt.h>
#include <string.h>
#include <mosquitto.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <signal.h>
#include <time.h>

#include "get_temperature.h"
#include "mqtt_txyun_conf.h"
#include "cJSON.h"
#include "dictionary.h"
#include "iniparser.h"

#define  PROG_VERSION "1.0.0"
#define  INI_PATH "./mqtt_txyun_conf.ini"

static int g_stop=0;

/* 调用信号 */
void sig_handler(int sig_num)
{
    if(sig_num == SIGUSR1)
    g_stop = 1;

}

int get_time(char *tim);
void connect_callback(struct mosquitto *mosq,void *obj,int rc);
static inline void print_usage(char *progname);


int main(int argc,char **argv)
{
    int 		rv;
    int 		port=1883;
    char 		*hostname=NULL;
    char 		*username=NULL;
    char 		*clientid=NULL;
    char 		*topic=NULL;
    char 		*passwd=NULL;

    char 		*program_name=basename(argv[0]);
    int 		daemon_run=0;
    int    		opt = -1;
    int			log_fd;

    data_mqtt 		mqtt;    
    struct mosquitto	*mosq = NULL;

   
    struct option options[] = 
    {
        {"daemon",no_argument,NULL,'d'},
        {"topic", required_argument,NULL,'t'},
        {"hostname", required_argument,NULL,'H'},
        {"clientid", required_argument, NULL, 'i'},
        {"port",required_argument,NULL,'p'},
        {"help",no_argument,NULL,'h'},
        {"username",required_argument,NULL,'u'},
        {"passwd",required_argument,NULL,'P'},
        {NULL,0,NULL,0}
    };

    while((opt = getopt_long(argc,argv,"dhp:t:i:u:P:H:",options,NULL)) != -1)
    {
        switch(opt)
        {
            case 't':
                topic = optarg;
                break;

            case 'i':
                clientid = optarg;
                break;

            case 'H':
                hostname = optarg;
                break;
            case 'u':
                username = optarg;
                break;
            case 'P':
                passwd = optarg;
                break;
            case 'd':
                daemon_run = 1;
                break;
            case 'p':
                port = atoi(optarg);
                break;
            case 'h':
                print_usage(argv[0]);
                return 0;
            default:
                break;
        }
    }   

      /* 创建日志 */
    if(daemon_run)
    {
        printf("program %s running in backgrund\n", program_name);
        if( (log_fd = open("client.log", O_CREAT|O_RDWR, 0666)) < 0)
        {
            printf("open() failed:%s\n", strerror(errno)) ;
            return -2;
        }

        dup2(log_fd, STDOUT_FILENO);
        dup2(log_fd, STDERR_FILENO);
        
        daemon(1,1);
    }

     /* 安装信号 */
    signal(SIGUSR1,sig_handler); 

    /* 载入配置文件 */
    memset(&mqtt,0,sizeof(mqtt));
    rv=get_mqtt_conf(INI_PATH,&mqtt,PUB);

    /* MQTT 初始化 */
    mosquitto_lib_init();

    /* 创建MQTT 客户端 */
    mosq = mosquitto_new(mqtt.clientid,true,(void *)&mqtt);

    if(!mosq)
    {
        printf("mosquitto_new() failed: %s\n",strerror(errno));
        goto cleanup;
        return -1;
    }

    /* 设置账号密码 */
    if(mosquitto_username_pw_set(mosq,mqtt.username,mqtt.passwd) != MOSQ_ERR_SUCCESS)
    {
        printf("mosquitto_username_pw_set failed: %s\n",strerror(errno));
        goto cleanup;
    }

     /* 设置回调函数 */
    mosquitto_connect_callback_set(mosq,connect_callback);

    
    while(!g_stop)
    {
        /* 连接MQTT服务器,ip,端口,时间 */
        if(mosquitto_connect(mosq, mqtt.hostname,mqtt.port,KEEP_ALIVE) != MOSQ_ERR_SUCCESS)
        {
             printf("mosquitto_connect() failed: %s\n",strerror(errno));
             goto cleanup;
        }
        printf("connect successful\n");

        /*无阻塞 断线连接 */
        mosquitto_loop_forever(mosq,-1,1);        

        sleep(3);
    }
    
            
/* 释放客户端,清除 */
cleanup:
    mosquitto_destroy(mosq);
    mosquitto_lib_cleanup();                
    return 0;
}


/* 获取时间 */
int get_time(char *tim)
{
    time_t          t;
    struct tm       *p;

    time(&t);
    p = gmtime(&t);

    snprintf(tim, 32, "%04d-%02d-%02d %02d:%02d:%02d", 1900+p->tm_year,1+p->tm_mon, p->tm_mday, (p->tm_hour + 8), p->tm_min, p->tm_sec);
    return 0 ;
}

/* 回调函数*/
void connect_callback(struct mosquitto *mosq,void *obj,int rc)
{
    float   tem = 0.00000000;
    char   tim[64];
    char *msg;

    cJSON   * root =  cJSON_CreateObject();
    cJSON   * item =  cJSON_CreateObject();

    memset(root,0,sizeof(root));
    memset(item,0,sizeof(item));
    memset(tim,0,sizeof(tim));

    if(get_temperature(&tem)<0)
    {
        printf("get_temperature failed:%s\n",strerror(errno));
        return ;
    }
    if(get_time(tim)<0)
    {
        printf("get_time failured:%s\n",strerror(errno));
        return ;
    }

    
    if(!obj)
    {
        printf("invalid_argument in %s\n",__FUNCTION__);
        return;
    }

     struct data_mqtt *mqtt = (data_mqtt *)obj;

    cJSON_AddItemToObject(root, "method", cJSON_CreateString(mqtt->method));
    cJSON_AddItemToObject(root, "id", cJSON_CreateString(mqtt->jsonid));
    cJSON_AddItemToObject(root, "params",item);
    cJSON_AddItemToObject(root,"time",cJSON_CreateString(tim));
    cJSON_AddItemToObject(item, "CurrentTemperature", cJSON_CreateNumber(tem));
    cJSON_AddItemToObject(root, "version", cJSON_CreateString(mqtt->version));
   
    msg=cJSON_Print(root);
    printf("%s\n",msg);

    if(!rc)
    {
         if(mosquitto_publish(mosq,NULL,mqtt->topic,strlen(msg),msg,mqtt->Qos,NULL) != MOSQ_ERR_SUCCESS)
         {
             printf("mosquitto_publish failed: %s\n",strerror(errno));
             return;
         }
     }    
    printf("mqtt_publish successful!\n");
   
    mosquitto_disconnect(mosq);

}

/* 帮助信息 */
void print_usage(char *progname)
{
    printf("%s usage:\n",progname);
    printf("Example: %s -h ${brokeraddress} -p ${brokerport} -i ${clientid} -u ${username} -p ${password} -t${topic} -h ${help} -d ${daemon}\n",progname);
    printf("-h(--host): sepcify hostname.\n");
    printf("-p(--port): sepcify port.\n");
    printf("-h(--Help): print this help information.\n");
    printf("-d(--daemon): set program running on background.\n");
    printf("-i(--clientid): sepcify the clientid.\n");
    printf("-u(--username): sepcify username of the client.\n");
    printf("-P(--passwd): sepcify password of the username.\n");
    printf("-t(--topic): sepcify topic of the client.\n");
    printf("-d(--daemon): running in backgrund.\n");
}

